﻿using System;
using System.Net.Sockets;
using System.Text;
using System.IO;

class TcpReverseProxyClient
{
    // 配置文件路径
    private const string ConfigFilePath = "client_config.json";

    static void Main(string[] args)
    {
        // 读取客户端配置文件
        ClientConfig config = ConfigManager.LoadClientConfig(ConfigFilePath);
        if (config == null)
        {
            Console.WriteLine("加载客户端配置文件失败，程序即将退出。");
            return;
        }

        string serverIp = config.ServerIp;  // 中转服务器 IP
        int serverPort = config.ServerPort;  // 中转服务器端口
        string clientId = config.ClientId;  // 客户端 ID
        string targetAddress = config.TargetAddress;  // 目标服务器地址

        try
        {
            // 创建与中转服务器的连接
            using (TcpClient tcpClient = new TcpClient(serverIp, serverPort))
            {
                NetworkStream stream = tcpClient.GetStream();
                Console.WriteLine("成功连接到中转服务器。");

                // 启动数据转发线程
                ForwardData(stream, targetAddress);
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"连接到中转服务器时发生错误：{ex.Message}");
        }
    }

    /// <summary>
    /// 启动数据转发线程，监听目标服务器的响应
    /// </summary>
    /// <param name="stream">中转服务器的网络流</param>
    /// <param name="targetAddress">目标服务器地址</param>
    private static void ForwardData(NetworkStream stream, string targetAddress)
    {
        byte[] targetAddressBytes = Encoding.UTF8.GetBytes(targetAddress);
        stream.Write(targetAddressBytes, 0, targetAddressBytes.Length);
        stream.Flush();
        Console.WriteLine($"已发送目标服务器地址: {targetAddress}");

        try
        {
            // 解析目标地址
            string[] addressParts = targetAddress.Split(':');
            if (addressParts.Length != 2)
            {
                Console.WriteLine($"目标地址格式不正确: {targetAddress}。正确的格式应为 IP:Port");
                return;
            }

            string targetIp = addressParts[0];
            int targetPort = int.Parse(addressParts[1]);

            using (TcpClient targetClient = new TcpClient())
            {
                targetClient.ReceiveTimeout = 5000;  // 设置接收超时为 5 秒
                targetClient.SendTimeout = 5000;     // 设置发送超时为 5 秒
                targetClient.Connect(targetIp, targetPort);  // 显式指定 TcpClient 类型

                NetworkStream targetStream = targetClient.GetStream();
                Console.WriteLine($"已成功连接到目标服务器：{targetIp}:{targetPort}");

                byte[] buffer = new byte[1024];

                while (true)
                {
                    // 从中转服务器接收数据并转发到目标服务器
                    int bytesRead = stream.Read(buffer, 0, buffer.Length);
                    if (bytesRead == 0) break;  // 客户端断开连接
                    Console.WriteLine($"从中转服务器接收到 {bytesRead} 字节数据，正在转发到目标服务器...");
                    targetStream.Write(buffer, 0, bytesRead);
                    targetStream.Flush();

                    // 从目标服务器接收数据并转发到中转服务器
                    bytesRead = targetStream.Read(buffer, 0, buffer.Length);
                    if (bytesRead == 0) break;  // 目标服务器断开连接
                    Console.WriteLine($"从目标服务器接收到 {bytesRead} 字节数据，正在转发到中转服务器...");
                    stream.Write(buffer, 0, bytesRead);
                    stream.Flush();
                }

                Console.WriteLine("数据转发结束，连接关闭。");
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"数据转发时发生错误：{ex.Message}");
        }
    }
}

/// <summary>
/// 客户端配置类，用于读取配置文件
/// </summary>
public class ClientConfig
{
    public string ServerIp { get; set; }
    public int ServerPort { get; set; }
    public string ClientId { get; set; }
    public string TargetAddress { get; set; }
}

/// <summary>
/// 配置管理器类，负责加载配置文件
/// </summary>
public static class ConfigManager
{
    /// <summary>
    /// 从 JSON 配置文件加载客户端配置
    /// </summary>
    public static ClientConfig LoadClientConfig(string filePath)
    {
        try
        {
            string json = File.ReadAllText(filePath);
            return Newtonsoft.Json.JsonConvert.DeserializeObject<ClientConfig>(json);
        }
        catch (Exception ex)
        {
            Console.WriteLine($"读取配置文件失败: {ex.Message}");
            return null;
        }
    }
}
